﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Threading;

namespace TestIonChannel
{
    public partial class Form1 : Form
    {
        //电量
        int QK = 0, QNa = 0;

        //平衡电位
        int EK = -80, ENa = 62;

        //电导
        int GAK = 9, GANa = 1;

        //通道数
        int ChannelCountK = 10, ChannelCountNa = 10;

        //当前电位
        int U = 0;

        Random R = new Random();

        public Form1()
        {
            this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer | ControlStyles.ResizeRedraw, true);

            InitializeComponent();
        }

        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);

            ThreadPool.QueueUserWorkItem(new WaitCallback(KIonChannelOperator), null);
            ThreadPool.QueueUserWorkItem(new WaitCallback(NaIonChannelOperator), null);
            ThreadPool.QueueUserWorkItem(new WaitCallback(NaKPumpOperator), null);
            //ThreadPool.QueueUserWorkItem(new WaitCallback(FirstMessengerS), null);
            //ThreadPool.QueueUserWorkItem(new WaitCallback(FirstMessengerI), null);
            //ThreadPool.QueueUserWorkItem(new WaitCallback(ProteinPhosphatase), null);

        }

        protected override void OnClosing(CancelEventArgs e)
        {
            base.OnClosing(e);
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            Us.Enqueue(U);
            if (Us.Count > pCenter.X) Us.Dequeue();

            this.Invalidate();
        }

        Queue<int> Us = new Queue<int>();
        Point pCenter = new Point(400, 100);
        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);

            Graphics G = e.Graphics;

            G.DrawLine(Pens.Green, 0, pCenter.Y, pCenter.X, pCenter.Y);
            G.DrawLine(Pens.Green, pCenter.X, 0, pCenter.X, pCenter.Y * 2);

            int[] parr = Us.ToArray();
            if (parr.Length > 0)
            {
                Point p1 = new Point(pCenter.X - Us.Count, pCenter.Y - parr[0]);

                for (int i = pCenter.X - Us.Count; i < pCenter.X; i++)
                {
                    Point p2 = new Point(i, pCenter.Y - parr[i - pCenter.X + Us.Count]);
                    G.DrawLine(Pens.Lime, p1, p2);
                    p1 = p2;
                }
                string sU = "U = " + U.ToString();
                string sQK = "QK = " + QK.ToString();
                string sQNa = "QNa = " + QNa.ToString();

                G.DrawString(sU, this.Font, Brushes.Yellow, new RectangleF(p1, G.MeasureString(sU, this.Font)));
                G.DrawString(sQK, this.Font, Brushes.Yellow, new RectangleF(new Point(pCenter.X + 50, 0), G.MeasureString(sQK, this.Font)));
                G.DrawString(sQNa, this.Font, Brushes.Yellow, new RectangleF(new Point(pCenter.X + 50, 20), G.MeasureString(sQNa, this.Font)));

            }
        }

        void KIonChannelOperator(object state)
        {
            while (true)
            {
                U = (int)((QK + QNa) * 0.001);

                QK -= (U - EK) * GAK * ChannelCountK;

                Thread.Sleep(R.Next(50, 100));
                //Thread.Sleep(100);
            }
        }

        void NaIonChannelOperator(object state)
        {
            while (true)
            {
                U = (int)((QK + QNa) * 0.001);

                QNa -= (U - ENa) * GANa * ChannelCountNa;

                Thread.Sleep(R.Next(50, 100));
            }
        }

        void NaKPumpOperator(object state)
        {
            while (true)
            {
                //离子泵
                if (QK < -10000 && QNa > 10000)
                {
                    QK += 2000;
                    QNa -= 2000;
                }

                Thread.Sleep(R.Next(50, 100));
            }
        }

        void FirstMessengerS(object state)
        {
            while (true)
            {
                ChannelCountNa += 90;

                Thread.Sleep(R.Next(5000, 6000));
            }
        }

        void FirstMessengerI(object state)
        {
            while (true)
            {
                ChannelCountK += 90;

                Thread.Sleep(R.Next(5000, 6000));
            }
        }

        void ProteinPhosphatase(object state)
        {
            while (true)
            {
                if (ChannelCountNa > 10) ChannelCountNa -= 10;
                if (ChannelCountK > 10) ChannelCountK -= 10;

                Thread.Sleep(R.Next(50, 100));
            }
        }

    }
}
